<?php

namespace api\controller;

use common\controller\VerifyController;
use common\exception\LogicException;
use common\model\DelayOrderTaskModel;
use common\service\DelayOrderService;
use common\service\DelayOrderTaskReviewWorkflowService;
use common\service\DelayOrderTaskService;
use common\validate\DelayOrder;
use support\ErrorCode;
use think\Exception;
use think\Request;
use think\Response;
use Throwable;
use Webman\Stomp\Client;

class DelayOrderController extends VerifyController
{
    /**
     * @var \common\service\DelayOrderService
     */
    private DelayOrderService $delayOrderService;
    private DelayOrderTaskReviewWorkflowService $delayOrderTaskReviewWorkflowService;


    public function __construct()
    {
        parent::__construct();
        $this->delayOrderService = DelayOrderService::getInstance();
        $this->delayOrderTaskReviewWorkflowService = DelayOrderTaskReviewWorkflowService::getInstance();
    }


    /**
     * 待延期申请任务分组列表
     * @param Request $request
     * @return Response
     */
    public function pendingDelayTaskGroupList(Request $request)
    {
        $taskIds = $request->param()['param']['filter']['task_ids'];
        $resData = $this->delayOrderService->pendingDelayTaskGroupList($taskIds);
        return json(success_response('', $resData));
    }

    /**
     * 创建延期单
     * @param Request $request
     * @return Response
     * @throws Throwable
     */
    public function createDelayOrder(Request $request)
    {
        $data = $request->param()['data'];

        $validate = new DelayOrder();
        // check reviewer
        $validate->scene('CheckDelayOrderReviewer');
        foreach ($data['reviewers'] ?? [] as $reviewerItem) {
            if (!$validate->check($reviewerItem)) {
                throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
            }
        }
        foreach ($data['delay_task_list'] as $delayTaskIndex => $delayTaskItem) {
            $validate->scene('CreateDelayOrderItem');
            if (!$validate->check($delayTaskItem)) {
                throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
            }
            $delayTaskItem['type'] = $delayTaskItem['type'] ?? DelayOrderTaskModel::TYPE_REQUEST_DELAY;
            $data['delay_task_list'][$delayTaskIndex] = $delayTaskItem;
        }

        try {
            $resData = $this->delayOrderService->createDelayOrder($data, $request->getUserId());
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 延期单列表
     * @param Request $request
     * @return Response
     */
    public function delayOrderList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->delayOrderService->delayOrderList($param, $request->getUserId());
        return json(success_response('', $resData));
    }

    /**
     * 延期单详情
     * @param Request $request
     * @return Response
     */
    public function delayOrderDetail(Request $request)
    {
        $delayOrderId = $request->param()['param']['filter']['delay_order_id'];
        $resData = $this->delayOrderService->delayOrderDetail($delayOrderId);
        return json(success_response('', $resData));
    }

    /**
     * 延期单列表 缩略
     * @param Request $request
     * @return Response
     */
    public function getDelayOrderListThumbnail(Request $request)
    {
        $param = $request->param();
        $resData = $this->delayOrderService->getDelayOrderListThumbnail($param);
        return json(success_response('', $resData));
    }

    /**
     * 批量创建延期
     * @param Request $request
     * @return Response
     * @throws Throwable
     */
    public function batchCreateDelayOrder(Request $request)
    {
        $data = $request->param()['data'];

        $validate = new DelayOrder();
        foreach ($data as $index => $datum) {
            $validate->scene('CreateDelayOrderArray');
            if (!$validate->check($datum)) {
                throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
            }
            foreach ($datum['delay_task_list'] as $delayTaskIndex => $delayTaskItem) {
                $validate->scene('CreateDelayOrderItem');
                if (!$validate->check($delayTaskItem)) {
                    throw_strack_exception($validate->getError(), ErrorCode::REQUEST_PARAM_ERROR);
                }
                $delayTaskItem['type'] = $delayTaskItem['type'] ?? DelayOrderTaskModel::TYPE_REQUEST_DELAY;
                $datum['delay_task_list'][$delayTaskIndex] = $delayTaskItem;
            }
            $data[$index] = $datum;
        }

        try {
            $resData = $this->delayOrderService->batchCreateDelayOrder($data, $request->getUserId());
            return json(success_response('', $resData));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 延期任务列表
     * @param Request $request
     * @return Response
     */
    public function delayTaskList(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->delayOrderService->delayTaskList($param);
        return json(success_response('', $resData));
    }

    /**
     * 获取环节下的延期原因标签
     * @param Request $request
     * @return Response
     */
    public function getStepCategoryDelayReason(Request $request)
    {
        $stepCategoryId = $request->param()['param']['filter']['step_category_id'];
        $resData = $this->delayOrderService->getStepCategoryDelayReason($stepCategoryId);
        return json(success_response('', $resData));
    }

    /**
     * 延期单审核流查询
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function selectReview(Request $request)
    {
        $projectId = $request->param()['param']['project_id'];
        $stepCategoryId = $request->param()['param']['step_category_id'];
        $resData = $this->delayOrderTaskReviewWorkflowService->selectReview($projectId, $stepCategoryId, $request->getUserId());
        return json(success_response('', $resData));
    }

    /**
     * 延期单审核详情
     * @param \think\Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function delayOrderReviewDetail(Request $request)
    {
        $param = $request->param()['param'];
        $resData = $this->delayOrderService->delayOrderReviewDetail($param, $request->getUserId());
        return json(success_response('', $resData));
    }

    /**
     * 受影响任务查询
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function effectedTaskList(Request $request)
    {
        $delayOrderId = $request->param()['param']['delay_order_id'];
        $resData = $this->delayOrderService->effectedTaskList($delayOrderId);
        return json(success_response('', $resData));
    }

    /**
     * 查找延期任务审核进度
     * @param \think\Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function findDelayOrderTaskReviewProgress(Request $request)
    {
        $taskId = $request->param()['param']['filter']['task_id'];
        $resData = $this->delayOrderService->findDelayOrderTaskReviewProgress($taskId);
        return json(success_response('', $resData));
    }

    /**
     * 延期环节列表
     * @param Request $request
     * @return Response
     */
    public function delayModuleStepCategoryList(Request $request)
    {
        $stepCategoryId = $request->param()['param']['step_category_id'];
        $projectId = $request->param()['param']['project_id'];
        $resData = $this->delayOrderService->delayModuleStepCategoryList($projectId, $stepCategoryId);
        return json(success_response('', $resData));
    }

    /**
     * 制片确认延期单
     * @param Request $request
     * @return Response
     * @throws Exception
     * @throws Throwable
     */
    public function managerConfirm(Request $request)
    {
        $delayOrderIdList = $request->param()['param']['delay_order_id_list'];
        $confirmStatus = $request->param()['param']['confirm_status'];
        $resData = $this->delayOrderService->managerConfirm($delayOrderIdList, $confirmStatus, $request->getUserId());
        return json(success_response('', $resData));
    }

    /**
     * 确认状态检查
     * @param Request $request
     * @return Response
     */
    public function confirmedCheck(Request $request)
    {
        $delayOrderIdList = $request->param()['param']['delay_order_id_list'];
        Client::send('delay_order_confirmed_check', build_queue_data_with_xu([
            'delay_order_id_list' => $delayOrderIdList,
            'user_id' => $request->getUserId(),
        ]));
        return json(success_response('', $delayOrderIdList));
    }

    /**
     * @param Request $request
     * @return Response
     */
    public function getDelayPackageICanConfirmCount(Request $request)
    {
        $param = $request->param()['param'] ?? [];
        $resData = DelayOrderTaskService::getInstance()->getDelayOrderTaskGrouped();

        return json(success_response('', $resData));
    }

    /**
     * @param Request $request
     * @return Response
     */
    public function getDelayOrderTaskGrouped(Request $request)
    {
        $param = $request->param()['param'] ?? [];
        $projectIds = $param['project_ids'] ?? [];
        $episodeCodes = $param['episode_codes'] ?? [];
        $startTime = $param['start_time'] ?? 0;
        $endTime = $param['end_time'] ?? 0;
        $taskName = $param['task_name'] ?? "";
        $stepCategoryIds = $param['step_category_ids'] ?? [];
        $delayCode = $param['code'] ?? [];
        $timeScope = [];
        if ($startTime > 0 && $endTime > 0) {
            $timeScope = [$startTime, $endTime];
        }

        $page = $param['page'] ?? [1, C('default_page_total')];
        $resData = DelayOrderTaskService::getInstance()->getDelayOrderTaskGrouped("list", 1, $page, $projectIds, $episodeCodes, $stepCategoryIds, $delayCode, $timeScope, $taskName);

        return json(success_response('', $resData));
    }


}
